/* 
 * File:   TBBComput.cpp
 * Author: amouro-m
 * 
 * Created on 31 mai 2010, 13:05
 */

#include "TBBCompute.h"

#include "tbb/parallel_for.h"
#include "tbb/tick_count.h"
#include "ResultPanel.h"

#include <iostream>
#include <sstream>

TBBCompute::TBBCompute(Computable* computable, FractalPrinter* fp, ResultPanel* result_panel):
_fp(fp),
_computable(computable),
_result_panel(result_panel)
{}

TBBCompute::~TBBCompute() {}

Computable*
TBBCompute::get_computable() const
{
    return _computable;
}

FractalPrinter*
TBBCompute::get_fractal_printer() const
{
    return _fp;
}

void
TBBCompute::operator ()(const tbb::blocked_range2d<unsigned int,unsigned int>& r) const
{
    tbb::blocked_range2d<unsigned int>::row_range_type rows = r.rows();
    tbb::blocked_range2d<unsigned int>::col_range_type cols = r.cols();

    tbb::tick_count start, end;
    start = tbb::tick_count::now();
    
    for (unsigned int i = rows.begin(); i < rows.end(); ++i)
        for (unsigned int j = cols.begin(); j < cols.end(); ++j)
            _computable->compute(_fp->get_area(), i, j);
    
    end = tbb::tick_count::now();
    tbb::tick_count::interval_t interval = (end - start);

    std::ostringstream os (std::ostringstream::out);
    os << _computable->print().toStdString()
            << " (" << rows.begin() << "," << rows.end() << "," << cols.begin() << "," << cols.end()
            << ") " << interval.seconds() << " s";
    std::string string(os.str());
    _result_panel->add_item(string.c_str());
    
    _fp->repaint();
}

void
TBBCompute::compute(Computable* computable, FractalPrinter* fp, Zone* zone, ResultPanel* result_panel)
{
    tbb::parallel_for(tbb::blocked_range2d<unsigned int, unsigned int>(zone->GetXmin(), zone->GetXmax(), zone->GetYmin(), zone->GetYmax()), TBBCompute(computable, fp, result_panel));
}